/*
 * usb_printf.cpp
 *
 *  Created on: Apr 4, 2013
 *      Author: r.leonov
 */

#include "usb.h"
#include "usb_printf.h"
#include "tiny_sprintf.h"

UsbCmd_t UsbCmd;

void UsbCmd_t::Task(){
    if(BufToHost.GetFullCnt()){
        uint8_t ReadBuf[BufToHost.GetFullCnt()];
        uint32_t ReadLength;
        ReadLength = BufToHost.GetFullCnt();
        BufToHost.Read(ReadBuf, &ReadLength);
//        CmdUnit.Printf("Buf (%u): %A", ReadLength, ReadBuf, ReadLength);
        Usb.Send(ReadBuf, ReadLength);
    }
}

void UsbCmd_t::Init(){
    BufToHost.Init();
}

void UsbCmd_t::Printf(const char *format, ...){
    char buf[100];
    va_list args;
    va_start(args, format);
    tiny_vsprintf(buf, format, args);
    va_end(args);

    for (int i = 0; buf[i] != 0; i++)
    BufToHost.WriteByte(buf[i]);
}


// Low level CircBuf
void CircBuf_t::WriteByte(uint8_t A){
    *PW++ = A;
    fcnt++;
    if(PW >= (Buf + BUF_SIZE)) PW = Buf;
}

void CircBuf_t::Write(uint8_t *PBuf, uint32_t ALength){
    for(uint8_t i = 0; i < ALength; i++){
        WriteByte(*PBuf++);
    }
}

bool CircBuf_t::Read(uint8_t *PBuf, uint32_t *PLength){
    if (fcnt == 0) return false;
    else {
        uint8_t Length;
        Length = (*PLength >= GetFullCnt())? GetFullCnt() : *PLength;
        while(Length){
            *PBuf++ = *PR++;
            if(PR >= (Buf + BUF_SIZE)) PR = Buf;
            fcnt--;
            Length--;
        }
        return true;
    }
}


